package com.server.limit.service;

import com.google.common.collect.Maps;
import com.google.common.util.concurrent.RateLimiter;
import com.server.limit.annotation.Limit;
import com.server.limit.constants.LimitStrategyConstants;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @title: RateLimitService
 * @author: gyuan
 * @description
 * @date: 2023-11-10 10:30
 */
@Service
public class RateLimitService extends AbstractLimitManagerService {

    private final Map<String, RateLimiter> rateLimiterMap = Maps.newConcurrentMap();

    @Override
    public boolean tryAccess(Limit limit) {
        RateLimiter rateLimiter = getLimit(limit);
        return rateLimiter.tryAcquire(limit.timeout(),limit.timeunit());
    }

    @Override
    protected String getStrategyName() {
        return LimitStrategyConstants.RATE_LIMIT;
    }

    /**
     * 获取限流处理器
     * @param limit
     * @return
     */
    private RateLimiter getLimit(Limit limit) {
        String key = limit.key();
        if(rateLimiterMap.containsKey(key)) {
            return rateLimiterMap.get(key);
        }
        RateLimiter rateLimiter = RateLimiter.create(limit.permitsPerSecond());
        rateLimiterMap.put(key, rateLimiter);
        return rateLimiter;
    }
}
